package com.langyiquan.service.impl;

import com.langyiquan.bo.SysDeptBo;
import com.langyiquan.exception.http.DeleteException;
import com.langyiquan.exception.http.ExistException;
import com.langyiquan.exception.http.NotFoundException;
import com.langyiquan.mapper.SysDeptMapper;
import com.langyiquan.mapper.SysUserMapper;
import com.langyiquan.pojo.SysDept;
import com.langyiquan.pojo.SysUser;
import com.langyiquan.service.SysDeptService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Service
public class SysDeptServiceImpl implements SysDeptService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    public final static String SEPARATOR = "-";

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveSysDept(SysDeptBo sysDeptBo) {
        if(_checkExist(sysDeptBo.getParentId(),sysDeptBo.getName())){
            throw new ExistException(2007);
        }

        SysDept sysDept = new SysDept();
        sysDept.setName(sysDeptBo.getName());
        sysDept.setParentId(sysDeptBo.getParentId());
        sysDept.setRemark(sysDeptBo.getRemark());
        sysDept.setSeq(sysDeptBo.getSeq());
        sysDept.setLevel(_getLevel(sysDeptBo.getParentId()));
        sysDept.setOperateIp(sysDeptBo.getOperatorIp());
        sysDept.setOperatorId(sysDeptBo.getOperatorId());
        sysDept.setUpdatedTime(new Date());
        sysDept.setCreatedTime(new Date());
        sysDeptMapper.insertSelective(sysDept);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public SysDept getSysDept(Integer deptId) {
        return sysDeptMapper.selectByPrimaryKey(deptId);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void deleteSysDept(Integer deptId) {

        SysDept sysDept = getSysDept(deptId);
        if(sysDept == null){
            throw new NotFoundException(2004);
        }

        SysDept query = new SysDept();
        query.setParentId(deptId);
        List<SysDept> list = sysDeptMapper.selectByExample(query);

        if(list.size() != 0){
            throw new DeleteException(2005);
        }

        // 查询部门下面是否还有员工

        Example example = new Example(SysUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("deptId",deptId);

        Integer sysUserCount = sysUserMapper.selectCountByExample(example);

        if(sysUserCount > 0){
            throw new DeleteException(2006);
        }

        sysDeptMapper.deleteByPrimaryKey(deptId);

    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateSysDept(SysDeptBo sysDeptBo) {

        if(_checkExist(sysDeptBo.getParentId(),sysDeptBo.getName())){
            throw new NotFoundException(2007);
        }
        SysDept sysDept = getSysDept(sysDeptBo.getId());
        Integer parentId = sysDept.getParentId();

        SysDept updateDept = new SysDept();

        BeanUtils.copyProperties(sysDeptBo,updateDept);
        sysDeptMapper.updateByPrimaryKeySelective(updateDept);

        if(parentId != sysDeptBo.getParentId()){
            SysDept query = new SysDept();
            query.setParentId(sysDeptBo.getId());
            List<SysDept> list = sysDeptMapper.selectByExample(query);
            for(SysDept dept : list){
                SysDept update = new SysDept();
                update.setId(dept.getId());
                update.setParentId(sysDeptBo.getId());
                update.setLevel(_getLevel(dept.getParentId()));
                sysDeptMapper.updateByPrimaryKeySelective(update);
            }
        }
    }

    private boolean _checkExist(Integer parentId,String deptName){
        Example example = new Example(SysDept.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",parentId);
        criteria.andEqualTo("name",deptName);
        SysDept sysDept = sysDeptMapper.selectOneByExample(example);
        return sysDept == null ? false : true;
    }

    public String _getLevel(Integer parentId){
        String level = null;
        SysDept sysDept = getSysDept(parentId);
        if(sysDept != null){
            level = sysDept.getLevel();
        }
        if(level == null){
            return "0";
        }else{
            return StringUtils.join(level,SEPARATOR,parentId);
        }

    }
}
